OS: Windows 10
Editor: Visual Studio Code
Rust version: 1.63.0
Rust的向量,是一個可以自動增長的陣列,連續的記憶體空間,建立方式如下:
// 建立一個i32的向量
let v: Vec<i32> = Vec::new();
注意!因為Vec
是泛型的關係,所以宣告的時候需要指定型別,所以以下這個寫法是非法的:
let v = Vec::new(); // 錯誤!不知道是什麼型別的集合
當然,如果已經有初始值的話,compiler會幫你辨識出這個向量是甚麼型別的:
let v = vec![1, 3, 5, 7]; // Vec<i32>
注意
vec![]
的!
,先前使用println!()
的時候也有這個符號,而這個符號表示Rust中的巨集(macro)。這個之後會介紹到。
要取得向量中的值的話,有兩種方式:
// Use []
let one = &v[0];
// Use `get()`
let two = v.get(1);
使用[]
會有潛在危險,如果索引(index)超出大小的話,沒辦法經過檢查,執行結果會直接出現exception:
let vec = vec![1, 3, 5, 7, 9];
let x = &vec[5];
println!("x is {}", x);
/*
* output:
* thread 'main' panicked at 'index out of bounds: the len is 5 but the index is 5', src\main.rs:4:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\basic.exe` (exit code: 101)
*/
使用get
的話,回傳的Option<T>
,這可以讓我們處理當取不到值的情況:
let vec = vec![1, 3, 5, 7, 9];
let x = vec.get(5);
match x {
Some(val) => println!("x is {}", val),
None => println!("Value not found"),
}
/*
* output:
* Value not found
*/
再來是一些常用最常用的加入與刪除
let mut vec = vec![1, 3, 5, 7, 9]; // 記得要變成"可變"
// 加入
vec.push(11);
// 刪除
let last = vec.pop(); // 這個回傳`Option<T>`
match last {
Some(val) => println!("x is {}", val),
None => println!("Value not found"),
}
由於Vec<T>
的底層實作是陣列,所以沒有實作插入(insert)或是push_front
之類的,這不合效益,如果從頭(head)加入好了,這會需要把整個陣列重新編排,如果有這種需求,應該要取使用Deque
之類的資料結構。
尋訪的會之前其實就有試過,有幾種不同的方法
let vec = vec![1, 3, 5, 7, 9];
// 使用index
for index in 0..vec.len() {
println!("{}", vec[index]);
}
// 遍歷
for v in &vec {
println!("{}", v);
}
// 同時拿出index與資料
for (index, item) in vec.iter().enumerate() {
println!("{} : {}", index, item);
}